﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using MediaServer.VideoCore;
using System.Threading;
using System.IO;
using System.Collections.Generic;

namespace MediaServer {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        AxAXISMEDIACONTROLLib.AxAxisMediaControl CameraControl = new AxAXISMEDIACONTROLLib.AxAxisMediaControl();
        public VideoCoreClient m_video = new VideoCoreClient();
       // public CameraCollection m_cameras = new CameraCollection();
        // stream is recording or not
        private bool m_isRecording = false;
        // flag, use for Stopping record stream
        private bool m_isStopRecord = false;
        private bool m_requestStopRecord = false;
        // duration time of a video
        int m_videoLength = 0;
        // root folder of raw video
        public const string ACTIVE_DIR = @"D:\CamVideos";
        // folder for a specific camera
        string newPath1;
        // folder for a specific camera on a specific day
        string newPath;
        // binding local server XML file with data grid
        private ObservableCollection<CameraModel> m_observerableCameras;
        public MainWindow() {
            InitializeComponent();
            using (VideoCoreClient client = new VideoCoreClient())
            {
                //MessageBox.Show(client.Welcome());
                var cams = client.GetCameraList();
                var lst = new List<CameraModel>();
                foreach (var item in cams)
                {
                    lst.Add(CameraModel.Create(item));
                }
                m_observerableCameras = new ObservableCollection<CameraModel>(lst);
                CameraControl.CreateControl();
                DataContext = m_observerableCameras;
                string IP = "10.0.6.51";
                newPath1 = System.IO.Path.Combine(ACTIVE_DIR, IP);
                System.IO.Directory.CreateDirectory(newPath1);
                newPath = System.IO.Path.Combine(newPath1, string.Format("{0:MM-dd-yyyy}", DateTime.Now));
                System.IO.Directory.CreateDirectory(newPath);
            }
        }
        

        private string CompleteURL(string theMediaURL, string theMediaType) {
            string anURL = theMediaURL;
            if (!anURL.EndsWith("/")) anURL += "/";

            if (theMediaType == "mjpeg") {
                anURL += "axis-cgi/mjpg/video.cgi";
            } else if (theMediaType == "mpeg4") {
                anURL += "mpeg4/media.amp";
            } else if (theMediaType == "h264") {
                anURL += "axis-media/media.amp?videocodec=h264";
            } else if (theMediaType == "mpeg2-unicast") {
                anURL += "axis-cgi/mpeg2/video.cgi";
            } else if (theMediaType == "mpeg2-multicast") {
                anURL += "axis-cgi/mpeg2/video.cgi";
            }

            anURL = CompleteProtocol(anURL, theMediaType);
            return anURL;
        }
        private string CompleteProtocol(string theMediaURL, string theMediaType) {
            if (theMediaURL.IndexOf("://") >= 0) return theMediaURL;

            string anURL = theMediaURL;

            if (theMediaType == "mjpeg") {
                anURL = "http://" + anURL;
            } else if (theMediaType == "mpeg4" || theMediaType == "h264") {
                anURL = "axrtsphttp://" + anURL;
            } else if (theMediaType == "mpeg2-unicast") {
                anURL = "http://" + anURL;
            } else if (theMediaType == "mpeg2-multicast") {
                anURL = "axsdp" + anURL;
            }

            return anURL;
        }
        private void OnAddNewCamera(object sender, RoutedEventArgs e) {
            string ip = tbCamIP.Text;
            string user = tbUsername.Text;
            string pass = pbPassword.Password;
            if ((Regex.Replace(ip, @"s+", "").Trim()) == "" | (Regex.Replace(user, @"s+", "").Trim()) == "" | (Regex.Replace(pass, @"s+", "").Trim()) == "") 
            {
                MessageBox.Show("IP, Username or Password can't be empty");
            }
            else
            {             
                // Remove may cho dung IPCamera o trong day
                // Dung CameraMode thay cho no
                // IPCamera chi de dung lam lien lac voi thang WCF
                // Qua day thi minh thay the no bang CameraModel
                // Va viet lai nhung thu can thiet 
                // May cai DataContract la de lien lac giua cac service voi nhau
                // Ko nen dung lam Model trong chuong trinh.
                IPCamera newCamera = new IPCamera() {
                    ID = Guid.NewGuid(),
                    Name = "Axis",
                    IPAddress = ip,
                    UserName = user,
                    Password = pass,
                    OnOff =(bool) cbOnOff.IsChecked,             
                };

                m_observerableCameras.Add(CameraModel.Create(newCamera));
                m_video.SaveIPCamera(newCamera);
            }
        }

        private void Connect(string url, string user, string password, string mediatype) {
            try {
                CameraHost.Child = CameraControl;
                CameraControl.Width = 480;
                CameraControl.Height = 480;
                CameraControl.MediaURL = url;
                CameraControl.MediaUsername = user;
                CameraControl.MediaPassword = password;
                CameraControl.MediaType = mediatype;
                CameraControl.MediaURL = CompleteURL(url, mediatype);
                CameraControl.Play();
                m_requestStopRecord = false;
            } catch (Exception ex) {
                MessageBox.Show(this, "Unable to play stream: " + ex.Message);
            }
        }

        /// <summary>
        /// Cho nay la dung Thread ne no tu recort cho may
        /// </summary>
        private void DoRecord() {
            DateTime currentSaveTime = DateTime.Now;
            int duration = 1;// Time of file you want to record (in minutes)
            string fileName = string.Format("{0:HHmmss}", currentSaveTime);
            
            if (!Directory.Exists(newPath))
            {
                try
                {
                    Directory.CreateDirectory(newPath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Cant create folder for recording");
                }
            }
            /// May lam the nay chua dc cai nay moi co the connect vo mot camera thoi
            /// Canlam ung voi moi~ cai camera thi no se~ co mot cai CameraControl tuong ung.
            /// Chu neu khong. Thi khi dang record thang nay. May Record thang khac nua thi no se mat thang dang xai
            /// Vi tui no xai chung mot control
            try {
                CameraControl.StartRecordMedia(newPath + @"\" + fileName + ".asf", 8, "");
                while (!m_requestStopRecord) {
                    if (DateTime.Now.Subtract(currentSaveTime).Minutes >= duration) {
                        CameraControl.StopRecordMedia();
                        Thread.Sleep(TimeSpan.FromSeconds(0.5));
                        fileName = string.Format("{0:HHmmss}", DateTime.Now);
                        CameraControl.StartRecordMedia(newPath + @"\" + fileName + ".asf", 8, "");
                        currentSaveTime = DateTime.Now;
                    }
                    
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
                CameraControl.StopRecordMedia();
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// Goi cho~ nay se tu dong chay thread record
        /// </summary>
        private void StartRecord() {
            Thread thread = new Thread(DoRecord);
            thread.Start();
        }

        private void DisConnect() {
            try {
                // Stop the stream (will also stop any recording in progress).
                CameraControl.Stop();
                m_isRecording = false;
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }
        private void dgCameraListSetup_SelectionChanged(object sender, SelectionChangedEventArgs e) {

        }
        private void StopRecord() {
            m_requestStopRecord = true;
        }
        private void dgCameraListSetup_Click(object sender, RoutedEventArgs e) {
            Button bnt = sender as Button;
            if (bnt != null) {
                Guid selectedId = ((Guid)bnt.Tag);
                var item = m_observerableCameras.FirstOrDefault(x => x.ID == selectedId);
                if (item.OnOff == false) {
                    item.OnOff = true;
                    MessageBox.Show(item.UserName + " " + item.IPAddress);
                    Connect(item.IPAddress, item.UserName, item.Password, "mjpeg");
                    StartRecord();
                } else {
                    item.OnOff = false;
                    StopRecord();
                }
            }
        }

        private void button2_Click(object sender, RoutedEventArgs e) {
            try{
            CameraControl.MediaURL = "10.0.6.51";
            CameraControl.MediaUsername = "toan";
            CameraControl.MediaPassword = "toan1";
            CameraControl.MediaType = "mjpeg";
            CameraControl.MediaURL = CompleteURL(CameraControl.MediaURL, CameraControl.MediaType);
            CameraControl.Play();
             m_requestStopRecord = false;
            } catch (Exception ex) {
                MessageBox.Show(this, "Unable to play stream: " + ex.Message);
            }
            StartRecord();

        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            
           
        }
    }
}

